package org.design.builderPattern;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * BuilderPattern
 * 建造者模式
 * 建造者模式是一种创建型设计模式，它允许你创建复杂对象的步骤与表示方式相分离。
 * 建造者模式是一种创建型设计模式，它的主要目的是将一个复杂对象的构建过程与其表示相分离，
 * 从而可以创建具有不同表示形式的对象。
 *
 * @author 樊温军
 * @date 2025/6/11 上午10:36
 */
public class BuilderPattern {
    public interface Item {
        String name();

        Packing packing();

        float price();
    }

    public interface Packing {
        String pack();
    }

    public class Wrapper implements Packing {

        @Override
        public String pack() {
            return "袋装";
        }
    }

    public class Bottle implements Packing {

        @Override
        public String pack() {
            return "瓶装";
        }
    }
    // 汉堡
    public abstract class Burger implements Item {

        @Override
        public Packing packing() {
            return new Wrapper();
        }

        @Override
        public abstract float price();
    }

    // 冷饮
    public abstract class ColdDrink implements Item {

        @Override
        public Packing packing() {
            return new Bottle();
        }

        @Override
        public abstract float price();
    }

    // 蔬菜汉堡
    public class VegBurger extends Burger {

        @Override
        public float price() {
            return 25.0f;
        }

        @Override
        public String name() {
            return "蔬菜汉堡";
        }
    }

    // 鸡肉汉堡
    public class ChickenBurger extends Burger {

        @Override
        public float price() {
            return 50.5f;
        }

        @Override
        public String name() {
            return "鸡肉汉堡";
        }
    }

    // 可乐
    public class Coke extends ColdDrink {

        @Override
        public float price() {
            return 30.0f;
        }

        @Override
        public String name() {
            return "可乐";
        }
    }

    // 百事可乐
    public class Pepsi extends ColdDrink {

        @Override
        public float price() {
            return 35.0f;
        }

        @Override
        public String name() {
            return "百事可乐";
        }
    }

    // 订单
    public class Meal {
        private List<Item> items = new ArrayList<>();

        public void addItem(Item item){
            items.add(item);
        }

        public float getCost(){
            float cost = 0.0f;
            for (Item item : items) {
                cost += item.price();
            }
            return cost;
        }

        public void showItems(){
            for (Item item : items) {
                System.out.print("项目 : "+item.name());
                System.out.print(", 包装方式 : "+item.packing().pack());
                System.out.println(", 价格 : "+item.price());
            }
        }
    }

    // 建造者
    public class MealBuilder {

        public Meal prepareVegMeal (){
            Meal meal = new Meal();
            meal.addItem(new VegBurger());
            meal.addItem(new Coke());
            return meal;
        }

        public Meal prepareNonVegMeal (){
            Meal meal = new Meal();
            meal.addItem(new ChickenBurger());
            meal.addItem(new Pepsi());
            return meal;
        }

        public Meal customMeal(List<? extends Item> items){
            Meal meal = new Meal();
            for (Item item : items) {
                meal.addItem(item);
            }
            return meal;
        }
    }

    @Test
    public void test() {
        BuilderPattern builderPattern = new BuilderPattern();
        MealBuilder mealBuilder = builderPattern.new MealBuilder();
        Meal vegMeal = mealBuilder.prepareVegMeal();
        System.out.println("素食订单");
        vegMeal.showItems();
        System.out.println("费用: " + vegMeal.getCost());

        Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
        System.out.println("\n\n肉食订单");
        nonVegMeal.showItems();
        System.out.println("费用: " + nonVegMeal.getCost());

        Meal customMeal = mealBuilder.customMeal(new ArrayList<Item>() {{
            add(new VegBurger());
            add(new Pepsi());
            add(new Coke());
            add(new ChickenBurger());
            add(new VegBurger());
        }});
        System.out.println("\n\n自定义订单");
        customMeal.showItems();
        System.out.println("费用: " + customMeal.getCost());

    }
}
